package top.hepingan.java.controller;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import top.hepingan.java.common.Result;
import top.hepingan.java.dto.RootDto;
import top.hepingan.java.entity.Frame;
import top.hepingan.java.entity.FrameUnlock;
import top.hepingan.java.entity.User;
import top.hepingan.java.mapper.FrameMapper;
import top.hepingan.java.mapper.FrameUnlockMapper;
import top.hepingan.java.mapper.UserMapper;
import top.hepingan.java.service.IUserService;
import top.hepingan.java.utils.AliUploadUtils;
import top.hepingan.java.utils.UserUtils;
import top.hepingan.java.utils.WechatUtil;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

@RequestMapping("/user")
@RestController
@Slf4j
@RequiredArgsConstructor
public class UserController {


    private final UserMapper userMapper;

    private final IUserService userService;

    private final AliUploadUtils aliUploadUtils;

    private final WechatUtil wechatUtil;

    @Value("${ali-oss.domain}")
    private String domain;

    @Value("${root-sercet}")
    private String rootSercet;
    /**
     * 登录
     * @param rootDto
     * @return
     */
    @PostMapping("/login")
    public Result login(@RequestBody RootDto rootDto){
        if (rootDto.getAdminKey() != null){
            if (!rootDto.getAdminKey().equals(rootSercet)){
                return Result.error("密钥错误");
            }
            User u = userMapper.selectOne(new QueryWrapper<User>().lambda()
                    .eq(User::getUsername, rootDto.getUsername())
                    .eq(User::getPassword, rootDto.getPassword())
                    .eq(User::getRole, "admin"));
            if (u != null){
                userMapper.updateById(u.setLastLoginTime(LocalDateTime.now()));
                StpUtil.login(u.getId());
                return Result.data(StpUtil.getTokenInfo());
            }else {
                return Result.error("检查账号是否为管理员账号 或密码错误 登录失败");
            }
        }
        User u = userMapper.selectOne(new QueryWrapper<User>().lambda()
                .eq(User::getUsername, rootDto.getUsername())
                .eq(User::getPassword, rootDto.getPassword()));
        if (u != null){
            // 判断是否是管理员，假设 u.getIsAdmin() 返回 true 表示是管理员
            userMapper.updateById(u.setLastLoginTime(LocalDateTime.now()));
            StpUtil.login(u.getId(),"user");  // 带身份登录
            return Result.data(StpUtil.getTokenInfo());
        }else {
            return Result.error("登录失败");
        }
    }

    /**
     * 注册
     * @param user
     * @return
     */
    @PostMapping("/register")
    public Result register(@RequestBody User user){
        User u = userMapper.selectOne(new QueryWrapper<User>().lambda()
                .eq(User::getUsername, user.getUsername()));
        if (u != null){
            return Result.error("用户名已存在");
        }else {
            user.setCreatedTime(LocalDateTime.now());
            user.setRole("user");
            user.setExperience(0);
            user.setLevel(1);
            user.setBackgroundImage("https://wpimg.wallstcn.com/e7d23d71-cf19-4b90-a1cc-f56af8c0903d.png");
            user.setAvatar("https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif");
            user.setLastLoginTime(LocalDateTime.now());
            userService.save(user);
            return Result.ok();
        }
    }

    @PostMapping("/updateUser")
    public Result updateUser(@RequestBody User user){
        User u = userMapper.selectOne(new QueryWrapper<User>().lambda()
                .eq(User::getId, UserUtils.getCurrentLoginId()));
        if (u != null){
            u.setUsername(user.getUsername());
            u.setPassword(user.getPassword());
            u.setAvatar(user.getAvatar());
            u.setPhone(user.getPhone());
            userService.updateById(u);
           return Result.ok();
        }else {
            return Result.error("用户不存在");
        }
    }

    @GetMapping("/getUserInfo")
    public Result getUserInfo(){
        User u = userMapper.selectById(UserUtils.getCurrentLoginId());
        return Result.data(u);
    }

    @GetMapping("/getUserInfoById")
    public Result getUserInfoById(Long userId){
        User u = userMapper.selectById(userId);
        return Result.data(u);
    }

    /**
     * 微信小程序登录
     * @return 登录结果
     */
    @PostMapping("/wx-login")
    public Result wxLogin(@RequestBody String code) {
        String openId = wechatUtil.getOpenId(code);
        User user = userMapper.selectOne(new QueryWrapper<User>().lambda().eq(User::getOpenId, openId));
        if (user == null) {
            user = new User();
            user.setOpenId(openId);
            user.setUsername("wx_"+openId.substring(0, 12));
            user.setPassword("123456");
            user.setRole("user");
            user.setExperience(0);
            user.setLevel(1);
            user.setBackgroundImage("https://wpimg.wallstcn.com/e7d23d71-cf19-4b90-a1cc-f56af8c0903d.png");
            user.setAvatar("https://img-hepingan.oss-cn-hangzhou.aliyuncs.com/page/f778738c-e4f8-4870-b634-56703b4acafe.gif");
            user.setCreatedTime(LocalDateTime.now());
            userMapper.insert(user);
            StpUtil.login(user.getId());
            return Result.data(StpUtil.getTokenInfo());
        }else {
            StpUtil.login(user.getId());
            return Result.data(StpUtil.getTokenInfo());
        }
    }

    /**
     * 上传背景图
     * @param file
     * @return
     */
    @PostMapping("/updateBackgroundImage")
    public Result updateBackgroundImage(@RequestBody MultipartFile file){
        String newFileName = generateRandomString();
        String url = aliUploadUtils.uploadFile(file, "link", newFileName+".jpg", true);
        User user = userMapper.selectOne(new QueryWrapper<User>().lambda().eq(User::getId, UserUtils.getCurrentLoginId()));
        user.setBackgroundImage(domain+url);
        userMapper.update(user, new QueryWrapper<User>().lambda().eq(User::getId, UserUtils.getCurrentLoginId()));
        return Result.data(domain + url);
    }

    /**
     * 更新头像
     * @param file
     * @return
     */
    @PostMapping(value = "/uploadAvatar")
    public Result uploadImg(@RequestBody MultipartFile file){
        String newFileName = generateRandomString();
        String url = aliUploadUtils.uploadFile(file, "link", newFileName+".jpg", true);
        User user = userMapper.selectOne(new QueryWrapper<User>().lambda().eq(User::getId, UserUtils.getCurrentLoginId()));
        aliUploadUtils.deleteFile(user.getAvatar());
        user.setAvatar(domain+url);
        userMapper.update(user, new QueryWrapper<User>().lambda().eq(User::getId, UserUtils.getCurrentLoginId()));
        return Result.data(domain + url);
    }

    private String generateRandomString() {
        String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        int STRING_LENGTH = 12;
        Random random = new Random();
        StringBuilder sb = new StringBuilder(STRING_LENGTH);
        for (int i = 0; i < STRING_LENGTH; i++) {
            int index = random.nextInt(CHARACTERS.length());
            sb.append(CHARACTERS.charAt(index));
        }
        return sb.toString();
    }

    private final FrameMapper frameMapper;

    private final FrameUnlockMapper frameUnlockMapper;
    @GetMapping("/frameList")
    public Result frameList(){
        List<Frame> frameList = frameMapper.selectList(new QueryWrapper<Frame>().lambda()
                .orderByAsc(Frame::getCreatedTime));
        return Result.data(frameList);
    }

    @GetMapping("/userFrameList")
    public Result UserFrameList(){
        List<FrameUnlock> frameUnlocks = frameUnlockMapper.selectList(new QueryWrapper<FrameUnlock>().lambda()
                .eq(FrameUnlock::getUserId, UserUtils.getCurrentLoginId()));
        List<Long> frameIds = frameUnlocks.stream().map(FrameUnlock::getFrameId).collect(Collectors.toList());
        return Result.data(frameIds);
    }

    @PostMapping("/updateFrame")
    public Result updateFrame(@RequestBody String url){
        User user = userMapper.selectOne(new QueryWrapper<User>().lambda().eq(User::getId, UserUtils.getCurrentLoginId()));
        user.setAvatarFrameUrl(url);
        userMapper.updateById(user);
        return Result.ok();
    }

    /**
     * 签到
     * @return
     */
    @GetMapping("/sign")
    public Result sign(){
        User user = userMapper.selectOne(new QueryWrapper<User>().lambda().eq(User::getId, UserUtils.getCurrentLoginId()));
        user.setExperience(user.getExperience()+5);
        checkLevel(user);
        userMapper.updateById(user);
        return Result.ok();
    }


    private void checkLevel(User user){
        if (user.getExperience() >= 100){
            user.setLevel(2);
        }
        if (user.getExperience() >= 300){
            user.setLevel(3);
        }
        if (user.getExperience() >= 500){
            user.setLevel(4);
        }
        if (user.getExperience() >= 1000){
            user.setLevel(5);
        }
        if (user.getExperience() >= 2000){
            user.setLevel(6);
        }
    }

}
